iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
0

成品連結:Follow Along Link Highlighter操作前程式碼完成後程式碼

今天要做的效果是當滑鼠 hover 至特定文字上時出現 highlight 的效果

我原本以為在 mouseenter 事件時加入 highlight 的 class 屬性就好,但後來發現這樣並不會有成品的效果;且從 CSS 可以看到 highlight 已設定 position: absolute,因此如果用我原本的方式被 mouseenter 的元素會跑到左上角,需要尋求其他辦法。以下解說~

首先把所有的 a 元素存入變數

const triggers = document.querySelectorAll('a');

創建 span 以顯示 highlight 效果

接著我們要創建新的元素 span 來顯示 highlight 的效果,所以要加上 highlight 的 class,並放到 HTML 當中

const highlight = document.createElement('span');
highlight.classList.add('highlight');
document.body.append(highlight);

此時 HTML 當中可以看到新建的元素,但畫面上卻看不到,因為我們還沒定義寬、高。

建立監聽事件

設定當滑鼠進入 a 時的事件

triggers.forEach(a => a.addEventListener('mouseenter', highlightLinks));

接著要完善 callback 的內容

function highlightLinks() {
    // code here
}

重點來了,這裡我們要使用 getBoundingClientRect() 來取得該 a 元素的寬、高以及之於左上角的位置,使用 console.log(this) 可以看到如下資訊

我們可以善用這些資訊來設定剛剛創建的 span 的大小及位置

function highlightLinks() {
    const linkCoords = this.getBoundingClientRect(); // 取得大小、位置資訊
    highlight.style.width = `${coords.width}px`;
    highlight.style.height = `${coords.height}px`;
    highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`
}

highlight 似乎會跑掉?

如成品的效果成功做出來了!但有個小問題,當滾動捲軸時 highlight 的效果會跑掉,這是因為當畫面載入時元素的位置(也就是 getBoundingClientRect()所獲得的資訊)已經固定,當滾動捲軸時並不會自動更新資訊。

解決辦法是加上滾動的距離(X 軸及 Y 軸都要),而滾動的距離我們可以透過 window.scrollX 以及 window.scrollY 取得

為避免 code 雜亂,我們新建一個 object 來儲存 highlight 所需要的資料

const coords = {
    width: linkCoords.width,
    height: linkCoords.height,
    top: linkCoords.top + window.scrollY,
    left: linkCoords.left + window.scrollX
}

並更新剛剛 highlight 的設定

highlight.style.width = `${coords.width}px`;
highlight.style.height = `${coords.height}px`;
highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`

完成!

Reference


上一篇
JS30 Day 21 - Geolocation
下一篇
JS30 Day 23 - Speech Synthesis
系列文
一起挑戰 JavaScript 30 吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言